﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using IPC.Communication.BasicFramework;
using IPC.Communication.Core;
using IPC.Communication.Core.Address;
using IPC.Communication.Core.Net;
using IPC.Communication.Reflection;
using IPC.Communication.Serial;

namespace IPC.Communication.ModBus
{
    public class ModbusTcpServer : NetworkDataServerBase
    {
        private List<ModBusMonitorAddress> subscriptions;

        private SimpleHybirdLock subcriptionHybirdLock;

        private SerialPort serialPort;

        private SoftBuffer coilBuffer;

        private SoftBuffer inputBuffer;

        private SoftBuffer registerBuffer;

        private SoftBuffer inputRegisterBuffer;

        private const int DataPoolLength = 65536;

        private int station = 1;

        public DataFormat DataFormat
        {
            get
            {
                return base.ByteTransform.DataFormat;
            }
            set
            {
                base.ByteTransform.DataFormat = value;
            }
        }

        public bool IsStringReverse
        {
            get
            {
                return base.ByteTransform.IsStringReverseByteWord;
            }
            set
            {
                base.ByteTransform.IsStringReverseByteWord = value;
            }
        }

        public int Station
        {
            get
            {
                return station;
            }
            set
            {
                station = value;
            }
        }

        public bool UseModbusRtuOverTcp
        {
            get;
            set;
        }

        public ModbusTcpServer()
        {
            coilBuffer = new SoftBuffer(65536);
            inputBuffer = new SoftBuffer(65536);
            registerBuffer = new SoftBuffer(131072);
            inputRegisterBuffer = new SoftBuffer(131072);
            registerBuffer.IsBoolReverseByWord = true;
            inputRegisterBuffer.IsBoolReverseByWord = true;
            subscriptions = new List<ModBusMonitorAddress>();
            subcriptionHybirdLock = new SimpleHybirdLock();
            base.ByteTransform = new ReverseWordTransform();
            base.WordLength = 1;
            serialPort = new SerialPort();
        }

        protected override byte[] SaveToBytes()
        {
            byte[] array = new byte[393216];
            Array.Copy(coilBuffer.GetBytes(), 0, array, 0, 65536);
            Array.Copy(inputBuffer.GetBytes(), 0, array, 65536, 65536);
            Array.Copy(registerBuffer.GetBytes(), 0, array, 131072, 131072);
            Array.Copy(inputRegisterBuffer.GetBytes(), 0, array, 262144, 131072);
            return array;
        }

        protected override void LoadFromBytes(byte[] content)
        {
            if (content.Length < 393216)
            {
                throw new Exception("File is not correct");
            }
            coilBuffer.SetBytes(content, 0, 0, 65536);
            inputBuffer.SetBytes(content, 65536, 0, 65536);
            registerBuffer.SetBytes(content, 131072, 0, 131072);
            inputRegisterBuffer.SetBytes(content, 262144, 0, 131072);
        }

        public bool ReadCoil(string address)
        {
            ushort index = ushort.Parse(address);
            return coilBuffer.GetByte(index) != 0;
        }

        public bool[] ReadCoil(string address, ushort length)
        {
            ushort index = ushort.Parse(address);
            return (from m in coilBuffer.GetBytes(index, length)
                    select m != 0).ToArray();
        }

        public void WriteCoil(string address, bool data)
        {
            ushort index = ushort.Parse(address);
            coilBuffer.SetValue((byte)(data ? 1 : 0), index);
        }

        public void WriteCoil(string address, bool[] data)
        {
            if (data != null)
            {
                ushort destIndex = ushort.Parse(address);
                coilBuffer.SetBytes(data.Select((bool m) => (byte)(m ? 1 : 0)).ToArray(), destIndex);
            }
        }

        public bool ReadDiscrete(string address)
        {
            ushort index = ushort.Parse(address);
            return inputBuffer.GetByte(index) != 0;
        }

        public bool[] ReadDiscrete(string address, ushort length)
        {
            ushort index = ushort.Parse(address);
            return (from m in inputBuffer.GetBytes(index, length)
                    select m != 0).ToArray();
        }

        public void WriteDiscrete(string address, bool data)
        {
            ushort index = ushort.Parse(address);
            inputBuffer.SetValue((byte)(data ? 1 : 0), index);
        }

        public void WriteDiscrete(string address, bool[] data)
        {
            if (data != null)
            {
                ushort destIndex = ushort.Parse(address);
                inputBuffer.SetBytes(data.Select((bool m) => (byte)(m ? 1 : 0)).ToArray(), destIndex);
            }
        }

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            bool isStartWithZero = true;
            OperateResult<ModbusAddress> operateResult = ModbusInfo.AnalysisAddress(address, (byte)Station, isStartWithZero = true, 3);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            if (operateResult.Content.Function == 3)
            {
                return OperateResult.CreateSuccessResult(registerBuffer.GetBytes(operateResult.Content.Address * 2, length * 2));
            }
            if (operateResult.Content.Function == 4)
            {
                return OperateResult.CreateSuccessResult(inputRegisterBuffer.GetBytes(operateResult.Content.Address * 2, length * 2));
            }
            return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            bool isStartWithZero = true;
            OperateResult<ModbusAddress> operateResult = ModbusInfo.AnalysisAddress(address, (byte)Station, isStartWithZero = true, 3);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            if (operateResult.Content.Function == 3)
            {
                registerBuffer.SetBytes(value, operateResult.Content.Address * 2);
                return OperateResult.CreateSuccessResult();
            }
            if (operateResult.Content.Function == 4)
            {
                inputRegisterBuffer.SetBytes(value, operateResult.Content.Address * 2);
                return OperateResult.CreateSuccessResult();
            }
            return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
        }

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            bool isStartWithZero = true;
            OperateResult<ModbusAddress> operateResult = ModbusInfo.AnalysisAddress(address, (byte)Station, isStartWithZero = true, 1);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            if (operateResult.Content.Function == 1)
            {
                return OperateResult.CreateSuccessResult((from m in coilBuffer.GetBytes(operateResult.Content.Address, length)
                                                          select m != 0).ToArray());
            }
            if (operateResult.Content.Function == 2)
            {
                return OperateResult.CreateSuccessResult((from m in inputBuffer.GetBytes(operateResult.Content.Address, length)
                                                          select m != 0).ToArray());
            }
            return new OperateResult<bool[]>(StringResources.Language.NotSupportedDataType);
        }

        [HslMqttApi("WriteBoolArray", "")]
        public override OperateResult Write(string address, bool[] value)
        {
            bool isStartWithZero = true;
            OperateResult<ModbusAddress> operateResult = ModbusInfo.AnalysisAddress(address, (byte)Station, isStartWithZero = true, 1);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            if (operateResult.Content.Function == 1)
            {
                coilBuffer.SetBytes(value.Select((bool m) => (byte)(m ? 1 : 0)).ToArray(), operateResult.Content.Address);
                return OperateResult.CreateSuccessResult();
            }
            if (operateResult.Content.Function == 2)
            {
                inputBuffer.SetBytes(value.Select((bool m) => (byte)(m ? 1 : 0)).ToArray(), operateResult.Content.Address);
                return OperateResult.CreateSuccessResult();
            }
            return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
        }

        [HslMqttApi("WriteBool", "")]
        public override OperateResult Write(string address, bool value)
        {
            if (address.IndexOf('.') < 0)
            {
                return base.Write(address, value);
            }
            try
            {
                int num = Convert.ToInt32(address.Substring(address.IndexOf('.') + 1));
                address = address.Substring(0, address.IndexOf('.'));
                bool isStartWithZero = true;
                OperateResult<ModbusAddress> operateResult = ModbusInfo.AnalysisAddress(address, (byte)Station, isStartWithZero = true, 3);
                if (!operateResult.IsSuccess)
                {
                    return operateResult;
                }
                num = operateResult.Content.Address * 16 + num;
                if (operateResult.Content.Function == 3)
                {
                    registerBuffer.SetBool(value, num);
                    return OperateResult.CreateSuccessResult();
                }
                if (operateResult.Content.Function == 4)
                {
                    inputRegisterBuffer.SetBool(value, num);
                    return OperateResult.CreateSuccessResult();
                }
                return new OperateResult(StringResources.Language.NotSupportedDataType);
            }
            catch (Exception ex)
            {
                return new OperateResult(ex.Message);
            }
        }

        public void Write(string address, byte high, byte low)
        {
            Write(address, new byte[2]
		{
			high,
			low
		});
        }

        //protected override void ThreadPoolLoginAfterClientCheck(Socket socket, IPEndPoint endPoint)
        //{
        //    AppSession appSession = new AppSession();
        //    appSession.IpEndPoint = endPoint;
        //    appSession.WorkSocket = socket;
        //    if (socket.BeginReceiveResult(SocketAsyncCallBack, appSession).IsSuccess)
        //    {
        //        AddClient(appSession);
        //    }
        //    else
        //    {
        //        if (base.LogNet != null)
        //        {
        //            base.LogNet.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, endPoint));
        //        }
        //    }
        //}

        //[AsyncStateMachine(typeof(<SocketAsyncCallBack>d__31))]
        //[DebuggerStepThrough]
        //private void SocketAsyncCallBack(IAsyncResult ar)
        //{
        //    <SocketAsyncCallBack>d__31 stateMachine = new <SocketAsyncCallBack>d__31();
        //    stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.ar = ar;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //}

        private byte[] CreateExceptionBack(byte[] modbusCore, byte error)
        {
            return new byte[3]
		{
			modbusCore[0],
			(byte)(modbusCore[1] + 128),
			error
		};
        }

        private byte[] CreateReadBack(byte[] modbusCore, byte[] content)
        {
            return SoftBasic.SpliceArray<byte>(new byte[3]
		{
			modbusCore[0],
			modbusCore[1],
			(byte)content.Length
		}, content);
        }

        private byte[] CreateWriteBack(byte[] modbus)
        {
            return modbus.SelectBegin(6);
        }

        private byte[] ReadCoilBack(byte[] modbus, string addressHead)
        {
            try
            {
                ushort num = base.ByteTransform.TransUInt16(modbus, 2);
                ushort num2 = base.ByteTransform.TransUInt16(modbus, 4);
                if (num + num2 > 65536)
                {
                    return CreateExceptionBack(modbus, 2);
                }
                if (num2 > 2040)
                {
                    return CreateExceptionBack(modbus, 3);
                }
                bool[] content = ReadBool(addressHead + num.ToString(), num2).Content;
                return CreateReadBack(modbus, SoftBasic.BoolArrayToByte(content));
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpReadCoilException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        private byte[] ReadRegisterBack(byte[] modbus, string addressHead)
        {
            try
            {
                ushort num = base.ByteTransform.TransUInt16(modbus, 2);
                ushort num2 = base.ByteTransform.TransUInt16(modbus, 4);
                if (num + num2 > 65536)
                {
                    return CreateExceptionBack(modbus, 2);
                }
                if (num2 > 127)
                {
                    return CreateExceptionBack(modbus, 3);
                }
                byte[] content = Read(addressHead + num.ToString(), num2).Content;
                return CreateReadBack(modbus, content);
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpReadRegisterException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        private byte[] WriteOneCoilBack(byte[] modbus)
        {
            try
            {
                if (!base.EnableWrite)
                {
                    return CreateExceptionBack(modbus, 4);
                }
                ushort num = base.ByteTransform.TransUInt16(modbus, 2);
                if (modbus[4] == byte.MaxValue && modbus[5] == 0)
                {
                    Write(num.ToString(), value: true);
                }
                else if (modbus[4] == 0 && modbus[5] == 0)
                {
                    Write(num.ToString(), value: false);
                }
                return CreateWriteBack(modbus);
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpWriteCoilException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        private byte[] WriteOneRegisterBack(byte[] modbus)
        {
            try
            {
                if (!base.EnableWrite)
                {
                    return CreateExceptionBack(modbus, 4);
                }
                ushort address = base.ByteTransform.TransUInt16(modbus, 2);
                short content = ReadInt16(address.ToString()).Content;
                Write(address.ToString(), modbus[4], modbus[5]);
                short content2 = ReadInt16(address.ToString()).Content;
                OnRegisterBeforWrite(address, content, content2);
                return CreateWriteBack(modbus);
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpWriteRegisterException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        private byte[] WriteCoilsBack(byte[] modbus)
        {
            try
            {
                if (!base.EnableWrite)
                {
                    return CreateExceptionBack(modbus, 4);
                }
                ushort num = base.ByteTransform.TransUInt16(modbus, 2);
                ushort num2 = base.ByteTransform.TransUInt16(modbus, 4);
                if (num + num2 > 65536)
                {
                    return CreateExceptionBack(modbus, 2);
                }
                if (num2 > 2040)
                {
                    return CreateExceptionBack(modbus, 3);
                }
                Write(num.ToString(), modbus.RemoveBegin(7).ToBoolArray(num2));
                return CreateWriteBack(modbus);
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpWriteCoilException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        private byte[] WriteRegisterBack(byte[] modbus)
        {
            try
            {
                if (!base.EnableWrite)
                {
                    return CreateExceptionBack(modbus, 4);
                }
                ushort num = base.ByteTransform.TransUInt16(modbus, 2);
                ushort num2 = base.ByteTransform.TransUInt16(modbus, 4);
                if (num + num2 > 65536)
                {
                    return CreateExceptionBack(modbus, 2);
                }
                if (num2 > 127)
                {
                    return CreateExceptionBack(modbus, 3);
                }
                MonitorAddress[] array = new MonitorAddress[num2];
                for (ushort num3 = 0; num3 < num2; num3 = (ushort)(num3 + 1))
                {
                    short content = ReadInt16((num + num3).ToString()).Content;
                    Write((num + num3).ToString(), modbus[2 * num3 + 7], modbus[2 * num3 + 8]);
                    short content2 = ReadInt16((num + num3).ToString()).Content;
                    array[num3] = new MonitorAddress
                    {
                        Address = (ushort)(num + num3),
                        ValueOrigin = content,
                        ValueNew = content2
                    };
                }
                for (int i = 0; i < array.Length; i++)
                {
                    OnRegisterBeforWrite(array[i].Address, array[i].ValueOrigin, array[i].ValueNew);
                }
                return CreateWriteBack(modbus);
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpWriteRegisterException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        private byte[] WriteMaskRegisterBack(byte[] modbus)
        {
            try
            {
                if (!base.EnableWrite)
                {
                    return CreateExceptionBack(modbus, 4);
                }
                ushort address = base.ByteTransform.TransUInt16(modbus, 2);
                int num = base.ByteTransform.TransUInt16(modbus, 4);
                int num2 = base.ByteTransform.TransUInt16(modbus, 6);
                int content = ReadInt16(address.ToString()).Content;
                short num3 = (short)((content & num) | num2);
                Write(address.ToString(), num3);
                MonitorAddress monitorAddress = default(MonitorAddress);
                monitorAddress.Address = address;
                monitorAddress.ValueOrigin = (short)content;
                monitorAddress.ValueNew = num3;
                MonitorAddress monitorAddress2 = monitorAddress;
                OnRegisterBeforWrite(monitorAddress2.Address, monitorAddress2.ValueOrigin, monitorAddress2.ValueNew);
                return modbus;
            }
            catch (Exception ex)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteException(ToString(), StringResources.Language.ModbusTcpWriteRegisterException, ex);
                }
                return CreateExceptionBack(modbus, 4);
            }
        }

        public void AddSubcription(ModBusMonitorAddress monitor)
        {
            subcriptionHybirdLock.Enter();
            subscriptions.Add(monitor);
            subcriptionHybirdLock.Leave();
        }

        public void RemoveSubcrption(ModBusMonitorAddress monitor)
        {
            subcriptionHybirdLock.Enter();
            subscriptions.Remove(monitor);
            subcriptionHybirdLock.Leave();
        }

        private void OnRegisterBeforWrite(ushort address, short before, short after)
        {
            subcriptionHybirdLock.Enter();
            for (int i = 0; i < subscriptions.Count; i++)
            {
                if (subscriptions[i].Address == address)
                {
                    subscriptions[i].SetValue(after);
                    if (before != after)
                    {
                        subscriptions[i].SetChangeValue(before, after);
                    }
                }
            }
            subcriptionHybirdLock.Leave();
        }

        private bool CheckModbusMessageLegal(byte[] buffer)
        {
            bool flag = false;
            switch (buffer[1])
            {
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                    flag = (buffer.Length == 6);
                    break;
                case 15:
                case 16:
                    flag = (buffer.Length > 6 && buffer[6] == buffer.Length - 7);
                    break;
                case 22:
                    flag = (buffer.Length == 8);
                    break;
                default:
                    flag = true;
                    break;
            }
            if (!flag)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteError(ToString(), "Receive Nosense Modbus-rtu : " + buffer.ToHexString(' '));
                }
            }
            return flag;
        }

        protected virtual byte[] ReadFromModbusCore(byte[] modbusCore)
        {
            switch (modbusCore[1])
            {
                case 1:
                    return ReadCoilBack(modbusCore, string.Empty);
                case 2:
                    return ReadCoilBack(modbusCore, "x=2;");
                case 3:
                    return ReadRegisterBack(modbusCore, string.Empty);
                case 4:
                    return ReadRegisterBack(modbusCore, "x=4;");
                case 5:
                    return WriteOneCoilBack(modbusCore);
                case 6:
                    return WriteOneRegisterBack(modbusCore);
                case 15:
                    return WriteCoilsBack(modbusCore);
                case 16:
                    return WriteRegisterBack(modbusCore);
                case 22:
                    return WriteMaskRegisterBack(modbusCore);
                default:
                    return CreateExceptionBack(modbusCore, 1);
            }
        }

        public void StartModbusRtu(string com)
        {
            StartModbusRtu(com, 9600);
        }

        public void StartModbusRtu(string com, int baudRate)
        {
            StartModbusRtu(delegate(SerialPort sp)
            {
                sp.PortName = com;
                sp.BaudRate = baudRate;
                sp.DataBits = 8;
                sp.Parity = Parity.None;
                sp.StopBits = StopBits.One;
            });
        }

        public void StartModbusRtu(Action<SerialPort> inni)
        {
            if (!serialPort.IsOpen)
            {
                if (inni != null)
                {
                    inni.Invoke(serialPort);
                }
                serialPort.ReadBufferSize = 1024;
                serialPort.ReceivedBytesThreshold = 1;
                serialPort.Open();
                serialPort.DataReceived += SerialPort_DataReceived;
            }
        }

        public void CloseModbusRtu()
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int num = 0;
            byte[] array = new byte[1024];
            int num2;
            do
            {
                Thread.Sleep(20);
                num2 = serialPort.Read(array, num, serialPort.BytesToRead);
                num += num2;
            }
            while (num2 != 0);
            if (num == 0)
            {
                return;
            }
            byte[] array2 = array.SelectBegin(num);
            if (array2.Length < 3)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteError(ToString(), "[" + serialPort.PortName + "] Uknown Data：" + array2.ToHexString(' '));
                }
                return;
            }
            if (array2[0] != 58)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteDebug(ToString(), "[" + serialPort.PortName + "] Rtu " + StringResources.Language.Receive + "：" + array2.ToHexString(' '));
                }
                if (SoftCRC16.CheckCRC16(array2))
                {
                    byte[] array3 = array2.RemoveLast(2);
                    if (!CheckModbusMessageLegal(array3))
                    {
                        return;
                    }
                    if (station >= 0 && station != array3[0])
                    {
                        if (base.LogNet != null)
                        {
                            base.LogNet.WriteError(ToString(), "[" + serialPort.PortName + "] Station not match Modbus-rtu : " + array2.ToHexString(' '));
                        }
                        return;
                    }
                    byte[] array4 = ModbusInfo.PackCommandToRtu(ReadFromModbusCore(array3));
                    serialPort.Write(array4, 0, array4.Length);
                    if (base.LogNet != null)
                    {
                        base.LogNet.WriteDebug(ToString(), "[" + serialPort.PortName + "] Rtu " + StringResources.Language.Send + "：" + array4.ToHexString(' '));
                    }
                    if (base.IsStarted)
                    {
                        RaiseDataReceived(sender, array2);
                    }
                }
                else
                {
                    if (base.LogNet != null)
                    {
                        base.LogNet.WriteWarn("[" + serialPort.PortName + "] CRC Check Failed : " + array2.ToHexString(' '));
                    }
                }
                return;
            }
            if (base.LogNet != null)
            {
                base.LogNet.WriteDebug(ToString(), "[" + serialPort.PortName + "] Ascii " + StringResources.Language.Receive + "：" + SoftBasic.GetAsciiStringRender(array2));
            }
            OperateResult<byte[]> operateResult = ModbusInfo.TransAsciiPackCommandToCore(array2);
            if (!operateResult.IsSuccess)
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteError(ToString(), operateResult.Message);
                }
                return;
            }
            byte[] content = operateResult.Content;
            if (!CheckModbusMessageLegal(content))
            {
                return;
            }
            if (station >= 0 && station != content[0])
            {
                if (base.LogNet != null)
                {
                    base.LogNet.WriteError(ToString(), "[" + serialPort.PortName + "] Station not match Modbus-Ascii : " + SoftBasic.GetAsciiStringRender(array2));
                }
                return;
            }
            byte[] array5 = ModbusInfo.TransModbusCoreToAsciiPackCommand(ReadFromModbusCore(content));
            serialPort.Write(array5, 0, array5.Length);
            if (base.LogNet != null)
            {
                base.LogNet.WriteDebug(ToString(), "[" + serialPort.PortName + "] Ascii " + StringResources.Language.Send + "：" + SoftBasic.GetAsciiStringRender(array5));
            }
            if (base.IsStarted)
            {
                RaiseDataReceived(sender, array2);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (subcriptionHybirdLock != null)
                {
                    subcriptionHybirdLock.Dispose();
                }
                if (subscriptions != null)
                {
                    subscriptions.Clear();
                }
                if (coilBuffer != null)
                {
                    coilBuffer.Dispose();
                }
                if (inputBuffer != null)
                {
                    inputBuffer.Dispose();
                }
                if (registerBuffer != null)
                {
                    registerBuffer.Dispose();
                }
                if (inputRegisterBuffer != null)
                {
                    inputRegisterBuffer.Dispose();
                }
                if (serialPort != null)
                {
                    serialPort.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        [HslMqttApi("ReadInt32Array", "")]
        public override OperateResult<int[]> ReadInt32(string address, ushort length)
        {
            IByteTransform transform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return ByteTransformHelper.GetResultFromBytes(Read(address, (ushort)(length * base.WordLength * 2)), (byte[] m) => transform.TransInt32(m, 0, length));
        }

        [HslMqttApi("ReadUInt32Array", "")]
        public override OperateResult<uint[]> ReadUInt32(string address, ushort length)
        {
            IByteTransform transform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return ByteTransformHelper.GetResultFromBytes(Read(address, (ushort)(length * base.WordLength * 2)), (byte[] m) => transform.TransUInt32(m, 0, length));
        }

        [HslMqttApi("ReadFloatArray", "")]
        public override OperateResult<float[]> ReadFloat(string address, ushort length)
        {
            IByteTransform transform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return ByteTransformHelper.GetResultFromBytes(Read(address, (ushort)(length * base.WordLength * 2)), (byte[] m) => transform.TransSingle(m, 0, length));
        }

        [HslMqttApi("ReadInt64Array", "")]
        public override OperateResult<long[]> ReadInt64(string address, ushort length)
        {
            IByteTransform transform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return ByteTransformHelper.GetResultFromBytes(Read(address, (ushort)(length * base.WordLength * 4)), (byte[] m) => transform.TransInt64(m, 0, length));
        }

        [HslMqttApi("ReadUInt64Array", "")]
        public override OperateResult<ulong[]> ReadUInt64(string address, ushort length)
        {
            IByteTransform transform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return ByteTransformHelper.GetResultFromBytes(Read(address, (ushort)(length * base.WordLength * 4)), (byte[] m) => transform.TransUInt64(m, 0, length));
        }

        [HslMqttApi("ReadDoubleArray", "")]
        public override OperateResult<double[]> ReadDouble(string address, ushort length)
        {
            IByteTransform transform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return ByteTransformHelper.GetResultFromBytes(Read(address, (ushort)(length * base.WordLength * 4)), (byte[] m) => transform.TransDouble(m, 0, length));
        }

        [HslMqttApi("WriteInt32Array", "")]
        public override OperateResult Write(string address, int[] values)
        {
            IByteTransform byteTransform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return Write(address, byteTransform.TransByte(values));
        }

        [HslMqttApi("WriteUInt32Array", "")]
        public override OperateResult Write(string address, uint[] values)
        {
            IByteTransform byteTransform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return Write(address, byteTransform.TransByte(values));
        }

        [HslMqttApi("WriteFloatArray", "")]
        public override OperateResult Write(string address, float[] values)
        {
            IByteTransform byteTransform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return Write(address, byteTransform.TransByte(values));
        }

        [HslMqttApi("WriteInt64Array", "")]
        public override OperateResult Write(string address, long[] values)
        {
            IByteTransform byteTransform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return Write(address, byteTransform.TransByte(values));
        }

        [HslMqttApi("WriteUInt64Array", "")]
        public override OperateResult Write(string address, ulong[] values)
        {
            IByteTransform byteTransform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return Write(address, byteTransform.TransByte(values));
        }

        [HslMqttApi("WriteDoubleArray", "")]
        public override OperateResult Write(string address, double[] values)
        {
            IByteTransform byteTransform = HslHelper.ExtractTransformParameter(ref address, base.ByteTransform);
            return Write(address, byteTransform.TransByte(values));
        }

        //[AsyncStateMachine(typeof(<ReadInt32Async>d__74))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<int[]>> ReadInt32Async(string address, ushort length)
        //{
        //    <ReadInt32Async>d__74 stateMachine = new <ReadInt32Async>d__74();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<int[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadUInt32Async>d__75))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<uint[]>> ReadUInt32Async(string address, ushort length)
        //{
        //    <ReadUInt32Async>d__75 stateMachine = new <ReadUInt32Async>d__75();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<uint[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadFloatAsync>d__76))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<float[]>> ReadFloatAsync(string address, ushort length)
        //{
        //    <ReadFloatAsync>d__76 stateMachine = new <ReadFloatAsync>d__76();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<float[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadInt64Async>d__77))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<long[]>> ReadInt64Async(string address, ushort length)
        //{
        //    <ReadInt64Async>d__77 stateMachine = new <ReadInt64Async>d__77();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<long[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadUInt64Async>d__78))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<ulong[]>> ReadUInt64Async(string address, ushort length)
        //{
        //    <ReadUInt64Async>d__78 stateMachine = new <ReadUInt64Async>d__78();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<ulong[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadDoubleAsync>d__79))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<double[]>> ReadDoubleAsync(string address, ushort length)
        //{
        //    <ReadDoubleAsync>d__79 stateMachine = new <ReadDoubleAsync>d__79();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<double[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__80))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, int[] values)
        //{
        //    <WriteAsync>d__80 stateMachine = new <WriteAsync>d__80();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.values = values;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__81))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, uint[] values)
        //{
        //    <WriteAsync>d__81 stateMachine = new <WriteAsync>d__81();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.values = values;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__82))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, float[] values)
        //{
        //    <WriteAsync>d__82 stateMachine = new <WriteAsync>d__82();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.values = values;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__83))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, long[] values)
        //{
        //    <WriteAsync>d__83 stateMachine = new <WriteAsync>d__83();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.values = values;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__84))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, ulong[] values)
        //{
        //    <WriteAsync>d__84 stateMachine = new <WriteAsync>d__84();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.values = values;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__85))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, double[] values)
        //{
        //    <WriteAsync>d__85 stateMachine = new <WriteAsync>d__85();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.values = values;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public override string ToString()
        {
            return String.Format("ModbusTcpServer[{0}]", base.Port);
        }
    }
}
